C言語でEfiMainを書く (1章:P43)
#ゼロからのOS自作入門
オプションが大量に・・・
code:build-command
$ clang -target x86_64-pc-win32-coff -mno-red-zone -fno-stack-protector -fshort-wchar -Wall -c ../src/hello.c
$ lld-link /subsystem:efi_application /entry:EfiMain /out:hello.efi hello.o
$ run_qemu.sh hello.efi
そもそも-mはmode、-fはflag
-mno-red-zoneも-fno-stack-protectorもフラグに見えるけど・・・
What do the -f and -m in gcc/clang compiler options stand for
-mno-red-zone
とりあえずred zoneが何なのかわからない
【C++】MSVCでAddressSanitizerを使ってみる
レッドゾーンはアクセス不能
スタックについて (マルチスレッドのプログラミング)
スレッドライブラリで生成される各スレッドスタックには、レッドゾーンがあります。スレッドライブラリはレッドゾーンとして、スタックオーバーフローを補足するためのページをスタックの一番上に付加します。このページは無効で、アクセスされるとメモリーフォルトになります。レッドゾーンは、自動的に割り当てられるすべてのスタックに付加されます。これは、その大きさがアプリケーションで指定されたかデフォルトの大きさかに関係なく行われます
「レッドゾーンとして、スタックオーバーフローを補足するためのページをスタックの一番上に付加」というのが重要な気がする
Why can't kernel code use a Red Zone
The 128-byte area beyond the location pointed to by %rsp is considered to be reserved and shall not be modified by signal or interrupt handlers. Therefore, functions may use this area for temporary data that is not needed across function calls. In particular, leaf functions may use this area for their entire stack frame, rather than adjusting the stack pointer in the prologue and epilogue. This area is known as the red zone.
「rsp(x86_64におけるスタックポインタ)の128バイト先はレッドゾーンと呼ばれる予約済み領域」とのこと
これはいわゆるコンパイラによる最適化で、ユーザーランドでは重宝することが多いものの、カーネル空間で割り込みが発生することを考慮するとややこしくなるらしい?
Libgcc without red zone
このサイトはWhyというかHowが書いてあるっぽい
(2022/01/23追記) P81に説明があった [rsp-??]みたいな記述は見た覚えがあったから、-mno-red-zoneでこれがなくなるのか!?と思ったけど、そんなことはなかった
https://scrapbox.io/files/620ce0a1d9e95f001d895ed4.png
-fno-stack-protector
LLVM Armバックエンド脆弱性 stack protectorとは何なのか - FPGA開発日記
スタックのローカル変数のスロットの前に、スタックプロテクタという領域を用意し、スタック領域がスタックプロテクタを超えてアクセス(というか、スタックプロテクタを踏んでしまった場合)を検知し、もしスタックプロテクタに格納されている値が関数の呼び出し時と関数から戻る時に異なっていた場合は、スタック領域を破壊したということで問題が発生したということにする。 これがスタックプロテクタの役割
-fshort-wchar
まあたぶんEFIの仕様が1文字あたり16ビットなUCS-2だから (P39)、文字列をそう解釈してコンパイルしてくれるんじゃないかな→ちょっと違いそう
そもそもL”Hello, World!”のL prefixを気にする必要がある
文字列リテラル
”str”の型はchar[N}に対し、L”str”の型はwchar_t[N]
clangのデフォルトは-fnoshort-wcharで、これはwchar_tを4バイトとするもの
-fshort-wcharはwchar_tを2バイトにするオプションらしい
算術型
shortは言語仕様では16ビット→2バイト以上でなければいけないらしいけど、shortとwchar_tは関係あるんだろうか
/subsystem:
efi_application用なんだろうなというのはわかるけど、それ以外何があるのか気になる
lld-link: error: subsystem must be defined
windowsやconsoleがあるらしい
公式ドキュメントっぽいのにも見当たらないし、ld-lldばっかり出てしまう
lld-link -helpの結果は /subsystem:<value> Specify subsystem らしいけど